﻿using Mapster;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NuGet.Protocol.Core.Types;
using QuickGet.Core;
using QuickGet.Core.Models;
using QuickGet.EntityFrameworkCore;
using QuickGet.EntityFrameworkCore.Models;

namespace QuickGet.Endpoints
{
    public static class PackageEndpoints
    {
        public static IEndpointRouteBuilder MapPackageEndpoints(this IEndpointRouteBuilder endpoints)
        {
            var group = endpoints.MapGroup("/package").WithTags("Package");

            group.MapPost("/search", SearchPackages).WithName(nameof(SearchPackages));
            group.MapGet("/versions", GetAllVersions).WithName(nameof(GetAllVersions));
            group.MapPost("/download", DownloadPackage).WithName(nameof(DownloadPackage));
            group.MapGet("/downloaded", ListDownloadedPackages).WithName(nameof(ListDownloadedPackages));

            return endpoints;
        }

        public static async Task<Ok<List<IPackageSearchMetadata>>> SearchPackages(
            [FromBody] SearchPackagesRequest request,
            [FromServices] SearchPackages action,
            [FromServices] IOperationCancellation operationCancellation)
        {
            var packages = await action.GetList(request, operationCancellation.Token);

            return TypedResults.Ok(packages);
        }

        public static async Task<Ok<List<string>>> GetAllVersions(
            [FromQuery] string id, [FromQuery] string source,
            [FromServices] ListPackageVersions action,
            [FromServices] IOperationCancellation operationCancellation)
        {
            var versions = await action.ExecuteAsync(new ListPackageVersionsCommand(id, source), operationCancellation.Token);

            return TypedResults.Ok(versions.OrderByDescending(x => x).Select(x => x.ToNormalizedString()).ToList());
        }

        public static async Task<Ok> DownloadPackage(
            [FromBody] DownloadPackageCommand command,
            [FromServices] DownloadPackage action,
            [FromServices] IOperationCancellation operationCancellation)
        {
            await action.ExecuteAsync(command, operationCancellation.Token);

            return TypedResults.Ok();
        }

        public static async Task<Ok<List<PackageVersionEntity>>> ListDownloadedPackages(
            [FromServices] AppDbContext db,
            [FromServices] IOperationCancellation operationCancellation)
        {
            var query = db.PackageVersions.AsNoTracking();

            var packages = await query.ToListAsync(operationCancellation.Token);

            return TypedResults.Ok(packages);
        }
    }
}
